const path = require("path");
import type { Configuration as WebpackConfiguration } from "webpack";
import type { Configuration as DevServerConfiguration } from "webpack-dev-server";
const TerserPlugin = require("terser-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const webpack = require("webpack");
const { PurgeCSSPlugin } = require("purgecss-webpack-plugin");
const glob = require("glob");
const CompressionPlugin = require("compression-webpack-plugin");
import commonConfig from "./common.config";
import { merge } from "webpack-merge";
const SpeedMeasurePlugin = require("speed-measure-webpack-v5-plugin");
const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer");

const ENABLE_SPEED = process.env.ENABLE_SPEED === "true";
const ENABLE_ANALYZER = process.env.ANALYZER === "true";

interface WebpackConfig extends WebpackConfiguration {
  devServer?: DevServerConfiguration;
}

const basePlugins = [
  new MiniCssExtractPlugin({
    filename: "css/[name].css",
    chunkFilename: "css/[name]_chunk.css",
  }),
  new webpack.optimize.ModuleConcatenationPlugin(),
  new PurgeCSSPlugin({
    paths: glob.sync(`${path.join(__dirname, "../src")}/**/*`, {
      nodir: true,
    }),
    safelist: {
      standard: ["html", "body"],
      deep: [],
      greedy: [],
    },
  }),
  new CompressionPlugin({
    filename: "[path][base].gz",
    algorithm: "gzip",
    test: /\.(js|css|html|svg)$/,
    threshold: 10240,
    minRatio: 0.8,
  }),
];

if (ENABLE_ANALYZER) {
  basePlugins.push(
    new BundleAnalyzerPlugin({
      analyzerMode: "server",
      analyzerPort: 8888,
      reportFilename: "report.html",
      openAnalyzer: true,
      generateStatsFile: true,
      statsFilename: "stats.json",
    })
  );
}

const prodConfig: WebpackConfig = merge(commonConfig, {
  mode: "production",
  optimization: {
    usedExports: true,
    concatenateModules: true,
    chunkIds: "deterministic",
    splitChunks: {
      chunks: "all",
      maxSize: 200000,
      minSize: 100,
      cacheGroups: {
        vendors: {
          test: /[\\/]node_modules[\\/]/,
          filename: "js/[name]_vendors.js",
        },
        utils: {
          test: /[\\/]src[\\/]utils[\\/]/,
          filename: "js/[name]_utils.js",
        },
      },
    },
    minimize: true,
    minimizer: [
      new TerserPlugin({
        extractComments: false,
        terserOptions: {
          compress: {
            arguments: true,
            unused: true,
            dead_code: true,
            drop_console: false,
            drop_debugger: true,
          },
          mangle: true,
          keep_fnames: true,
        },
      }),
      new CssMinimizerPlugin(),
    ],
    sideEffects: true,
    innerGraph: true,
  },
  plugins: basePlugins,
});

module.exports = prodConfig;
